
package com.lee.utils; 
 
import com.lee.logger.Logger; 
 
import java.util.ArrayList; 
import java.util.List; 
 
public class ArrayUtils { 
 
    public static List<List<Long>> addItemToListGinix(List<List<Long>> data, long item) {
 
        List<Long> lastData = new ArrayList<>(data.get(data.size() - 1));
        Long end = lastData.get(1);
        List<Long> firstData = new ArrayList<>(data.get(0));
        Long start = firstData.get(0);
 
        List<List<Long>> newDataList = new ArrayList<>();
        //新增数据在已有区间最右侧，且相邻
        if (item > end && item - end == 1) {
            Logger.debug("addItemToListGinix -> 添加数据到最右侧，且相邻",item);
            lastData.set(1, item);
            newDataList.addAll(data);
            newDataList.set(newDataList.size() - 1, lastData);
            return newDataList;
        }
        //新增数据在已有区间最右侧，且不相邻
        else if (item > end) {
            Logger.debug("addItemToListGinix -> 添加数据到最右侧，且相邻",item);
            List<Long> newData = new ArrayList<>();
            newData.add(item);
            newData.add(item);
            newDataList.addAll(data);
            newDataList.add(newData);
            return newDataList;
        }
        //新增数据在已有区间最左侧，且相邻
        else if (start > item && start - item == 1) {
            Logger.debug("addItemToListGinix -> 添加数据到最左侧，且相邻",item);
            firstData.set(0, item);
            newDataList.addAll(data);
            newDataList.set(0, firstData);
            return newDataList;
        }
        //新增数据在已有区间最左侧，且不相邻
        else if (start > item) {
 
            Logger.debug("addItemToListGinix -> 添加数据到最左侧，且不相邻",item);
            List<Long> newData = new ArrayList<>();
            newData.add(item);
            newData.add(item);
            newDataList.add(newData);
            newDataList.addAll(data);
            return newDataList;
        } else {
            for (int i = 0; i < data.size() - 1; i++) {
                //新增数据在已有区间间隔中，且不相邻左侧和右侧区间
                if (data.get(i).get(1) < item - 1 && data.get(i + 1).get(0) > item + 1) {
                    Logger.debug("addItemToListGinix -> 新增数据在已有区间间隔中，且不相邻左侧和右侧区间",item);
                    List<Long> newData = new ArrayList<>();
                    newData.add(item);
                    newData.add(item);
                    newDataList.addAll(data.subList(0, i + 1));
                    newDataList.add(newData);
                    newDataList.addAll(data.subList(i + 1, data.size()));
                    return newDataList;
                }
                //新增数据在已有区间间隔中，且与左侧和右侧间隔相邻
                else if (data.get(i).get(1) == item - 1 && data.get(i + 1).get(0) == item + 1) {
                    Logger.debug("addItemToListGinix -> 新增数据在已有区间间隔中，且与左侧和右侧间隔相邻",item);
                    List<Long> newData = new ArrayList<>();
                    newData.add(data.get(i).get(0));
                    newData.add(data.get(i + 1).get(1));
                    newDataList.addAll(data.subList(0, i));
                    newDataList.add(newData);
                    newDataList.addAll(data.subList(i + 2, data.size()));
                    return newDataList;
                }
                //新增数据在已有区间间隔中，且与左侧间隔相邻
                else if (data.get(i).get(1) == item - 1 && data.get(i + 1).get(0) > item + 1) {
                    Logger.debug("addItemToListGinix -> 新增数据在已有区间间隔中，且与左侧间隔相邻",item);
                    List<Long> leftData = new ArrayList<>(data.get(i));
                    leftData.set(1, item);
                    newDataList.addAll(data);
                    newDataList.set(i, leftData);
                    return newDataList;
                }
                //新增数据在已有区间间隔中，且与右侧间隔相邻
                else if (data.get(i).get(1) < item - 1 && data.get(i + 1).get(0) == item + 1) {
                    Logger.debug("addItemToListGinix -> 新增数据在已有区间间隔中，且与右侧间隔相邻",item);
                    List<Long> leftData = new ArrayList<>(data.get(i + 1));
                    leftData.set(0, item);
                    newDataList.addAll(data);
                    newDataList.set(i+1, leftData);
                    return newDataList;
                }
 
            }
        }
        return data;
    }
    public static<T> List<T> getSameItem(List<T> array1,List<T> array2){
        List<T> arrayResult = new ArrayList<>();
        array1.stream().forEach(item->{
            if(array2.contains(item) && ! arrayResult.contains(item)){
                arrayResult.add(item);
            }
        });
        return arrayResult;
    }
    public static List<List<Long>> getSameItemGinix(List<List<Long>> array1, List<List<Long>> array2){
        List<List<Long>> arrayResult = new ArrayList<>();
        array1.stream().forEach(item->{
 
            long array1Start = item.get(0);
            long array1End = item.get(1);
            array2.stream().forEach(rItem->{
 
                long array2Start = rItem.get(0);
                long array2End = rItem.get(1);
 
                long maxStart = Math.max(array1Start,array2Start);
                long minEnd = Math.min(array1End,array2End);
                if (maxStart <= minEnd){
                    //满足区间相交
                    List<Long> newData = new ArrayList<>();
                    newData.add(maxStart);
                    newData.add(minEnd);
                    arrayResult.add(newData);
                }
            });
        });
        return arrayResult;
    }
    public static long getItemSizeGinix(List<List<Long>> array){
        long size = 0;
        for(List<Long> item:array){
            long start = item.get(0);
            long end = item.get(1);
            size += Math.abs(end - start + 1);
        }
        // 进行laplace加噪
        size = LaplaceUtils.laplaceMeth(size);
        return size;
 
    }
    public static <T> List<T> getUniqItem(List<T> array1,List<T> array2){
        List<T> arrayResult = new ArrayList<>();
        array1.stream().forEach(item->{
            if(!arrayResult.contains(item)){
                arrayResult.add(item);
            }
        });
        array2.stream().forEach(item->{
            if(!arrayResult.contains(item)){
                arrayResult.add(item);
            }
        });
        return arrayResult;
 
    }
 
 
    public static <T> List<T> getSubItem(List<T> parentArray,List<T> array){
        List<T> arrayResult = new ArrayList<>();
        parentArray.stream().forEach(item->{
            if(! array.contains(item) && ! arrayResult.contains(item)){
                arrayResult.add(item);
            }
        });
        return arrayResult;
    }
    public static <T> boolean isSubArray(List<T> subArray,List<T> parentArray){
        boolean isSubArray = true;
        for(T item:subArray){
            if(!parentArray.contains(item)){
                isSubArray = false;
                break;
 
            }
        }
        return isSubArray;
    }
 
    public static <T> boolean isListItemInArray(List<T> listItem,List<List<T>> array){
        boolean isListItemInArray = false;
        for(List<T> arrayItem:array){
            if(isEqual(listItem,arrayItem)){
                isListItemInArray = true;
                break;
            }
        }
        return isListItemInArray;
    }
 
    public static <T> boolean isEqual(List<T> array1,List<T> array2){
        boolean isEqual = true;
        if(array1.size() != array2.size()){
            isEqual = false;
 
        } else{
            for(T item:array1){
                if(!array2.contains(item)){
                    isEqual = false;
                    break;
                }
            }
            for(T item:array2){
                if(!array1.contains(item)){
                    isEqual = false;
                    break;
                }
            }
        }
        return isEqual;
    }
} 
